package com.hhf.rpa.InputDeviceMonitor.impl1;

import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;

public class KeyboardHook implements Runnable {

	private WinUser.HHOOK hhk;

	static {
		System.loadLibrary("user32");
	}
 
	// 钩子回调函数
	private WinUser.LowLevelKeyboardProc keyboardProc = new WinUser.LowLevelKeyboardProc()
	{
		@Override
		public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT event)
		{
			// 输出按键值和按键时间
			if (nCode >= 0) {
				int vkCode= event.vkCode;
				// 检查是否按下了Shift键
				boolean isShiftPressed = (event.flags & WinUser.VK_SHIFT) != 0;
				// 创建一个256字节的数组来存储键盘状态
				byte[] keyboardState = new byte[256];
				/*// 获取当前输入语言的键盘布局句柄
				WinDef.HKL currentLayout = User32.INSTANCE.GetKeyboardLayout(0);

				// 使用JNI调用MapVirtualKey函数， 将虚拟键码转换为扫描码
				int scanCode = User32.INSTANCE.MapVirtualKeyEx(vkCode, 0, currentLayout);
				char c = (char) scanCode;*/
				char c = (char)vkCode;

				// 如果是字母并且按下了Shift键，则转换为大写
				if (Character.isLetter(c) && isShiftPressed) {
					c = Character.toUpperCase(c);
				} else {
					c = Character.toLowerCase(c);
				}

				System.out.println(vkCode + "," + c);

				// 按下F7退出
				if (event.vkCode == 118)
				{
					KeyboardHook.this.setHookOff();
					System.exit(0);
				}
			}
			
			return User32.INSTANCE.CallNextHookEx(hhk, nCode, wParam, null);
		}
	};


	private native int MapVirtualKey(int uCode, int uMapType);
 
	public void run()
	{
		setHookOn();
	}
 
	// 安装钩子
	public void setHookOn()
	{
		WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		hhk = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardProc, hMod, 0);
		
		int result;
		WinUser.MSG msg = new WinUser.MSG();
		while ((result = User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)
		{
			if (result == -1)
			{
				setHookOff();
				break;
			} else
			{
				User32.INSTANCE.TranslateMessage(msg);
				User32.INSTANCE.DispatchMessage(msg);
			}
		}
	}
 
	// 移除钩子并退出
	public void setHookOff()
	{
		User32.INSTANCE.UnhookWindowsHookEx(hhk);
	}
}
